﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace FlexiPay
{
    public partial class SlabStructure : System.Web.UI.Page
    {
        #region page member&method
        private static MatrixTable matrix;

        protected void Page_Init(object sender, EventArgs e)
        {
            if (matrix != null)
            {
                createMatrixStructure();
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
        }
        #endregion

        #region retrieve the data on initialization
        protected void LBSlabs_DataBound(object sender, EventArgs e)
        {
            ManageEditables(false);
            ButtonEdit.Visible = false;
        }

        protected void LBSlabs_SelectedIndexChanged(object sender, EventArgs e)
        {
            //clear it before display
            PanelTable.Controls.Clear();

            matrix = new MatrixTable(Convert.ToInt32(LBSlabs.SelectedValue));
            retrieveSlabDetails();
            createMatrixStructure();
            loadMatrix();
            ManageEditables(false);
        }

        private void retrieveSlabDetails()
        {
            int SlabId = Convert.ToInt32(LBSlabs.SelectedValue);

            //retieve upper part
            string selectQuery = "select [SlabName],[FromDate],[ToDate],[ROperator],[COperator],[Status], [IsStepped], [RFormula], [CFormula] " +
                "from [Slabs] where [SlabId]='" + SlabId.ToString() + "'";
            DataTable dt = DataBaseMethods.ExecuteSelectQuery(selectQuery);

            //set upper values
            TextBoxName.Text = dt.Rows[0][0].ToString();
            TextBoxFrom.Text = Convert.ToDateTime(dt.Rows[0][1].ToString()).ToString("dd-MMM-yyyy");
            TextBoxTo.Text = Convert.ToDateTime(dt.Rows[0][2].ToString()).ToString("dd-MMM-yyyy");
            DropDownList2.SelectedValue = dt.Rows[0][3].ToString();
            DropDownList4.SelectedValue = dt.Rows[0][4].ToString();
            DDLStatus.SelectedValue = dt.Rows[0][5].ToString();
            DropDownList5.SelectedValue = dt.Rows[0][6].ToString().Trim();
            DDLFunctionR.SelectedValue = dt.Rows[0][7].ToString();
            DDLFunctionC.SelectedValue = dt.Rows[0][8].ToString();

            //set dimensions
            DropDownList1.SelectedValue = matrix.getRowCount().ToString();
            DropDownList3.SelectedValue = matrix.getColumnCount().ToString();
        }

        private void ManageEditables(bool editable)
        {
            //manage buttons
            ButtonApply.Visible = editable;
            ButtonCancel.Visible = editable;
            ButtonEdit.Visible = !editable;
            ButtonCreate.Visible = !editable;

            //manage panels
            panelMiddleInner.Enabled = editable;
            PanelUpper.Enabled = editable;

            //formula for  column
            if (DropDownList3.SelectedValue.ToString() == "1")
                DropDownList4.Enabled = DDLFunctionC.Enabled = false;
            else
                DropDownList4.Enabled = DDLFunctionC.Enabled = true;
        }

        protected void DropDownList3_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Convert.ToInt32(DropDownList3.SelectedValue) > 1)
            {
                DropDownList4.Enabled = true;
                DDLFunctionC.Enabled = true;
            }
            else
            {
                DropDownList4.Enabled = false;
                DDLFunctionC.Enabled = false;
                DDLFunctionC.SelectedValue = 11.ToString();
            }
        }
        #endregion

        #region button clicks
        protected void ButtonEdit_Click(object sender, EventArgs e)
        {
            ManageEditables(true);
            //PanelUpper.Enabled = false;
        }

        protected void ButtonCancel_Click(object sender, EventArgs e)
        {
            if (LBSlabs.SelectedIndex < 0) return;
            LBSlabs_SelectedIndexChanged(sender, e);
        }

        protected void ButtonCreate_Click(object sender, EventArgs e)
        {
            matrix = null;
            ManageEditables(true);
            resetValues();
        }

        private void resetValues()
        {
            TextBoxName.Text = "Untitled_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
            TextBoxFrom.Text = DateTime.Now.ToString("dd-MMM-yyyy");
            TextBoxTo.Text = DateTime.Now.AddYears(1).ToString("dd-MMM-yyyy");

            DropDownList1.SelectedIndex = 4;
            DropDownList2.SelectedIndex = 0;
            DropDownList3.SelectedIndex = 4;
            DropDownList4.SelectedIndex = 4;
            DropDownList5.SelectedIndex = 0;
            DDLStatus.SelectedIndex = 0;
            DDLFunctionC.SelectedValue = 11.ToString();
            DDLFunctionR.SelectedValue = 11.ToString();

            panelMiddleInner.Controls.Clear();
            panelMiddleInner.Enabled = false;
        }

        protected void ButtonApply_Click(object sender, EventArgs e)
        {
            //slab details are non-updatable, so update them only when its new
            int slab_id = updateSlabsTable();

            //create and insert matrix
            int rows = Convert.ToInt32(DropDownList1.SelectedValue.ToString());
            int cols = Convert.ToInt32(DropDownList3.SelectedValue.ToString());
            string rop = DropDownList2.SelectedValue.ToString();
            string cop = DropDownList4.SelectedValue.ToString();

            //if its creating new, store to db directly
            if (matrix == null)
                matrix = new MatrixTable(slab_id, rows, rop, cols, cop);
            else
                matrix.updateMatrix2DB(saveMatrix());

            //bind the data and then display
            LBSlabs.DataBind();
            LBSlabs.SelectedValue = slab_id.ToString();
            LBSlabs_SelectedIndexChanged(sender, e);

            return;
        }

        private int updateSlabsTable()
        {
            //retieve values to insert
            string slabName = TextBoxName.Text.ToString();
            DateTime fromDate = Convert.ToDateTime(TextBoxFrom.Text.ToString());
            DateTime toDate = Convert.ToDateTime(TextBoxTo.Text.ToString());
            string slabType = DropDownList5.SelectedValue.ToString();
            int rowC = Convert.ToInt32(DropDownList1.SelectedValue.ToString());
            int colC = Convert.ToInt32(DropDownList3.SelectedValue.ToString());
            string rowOp = DropDownList2.SelectedValue.ToString();
            string colOp = DropDownList4.SelectedValue.ToString();
            string status = DDLStatus.SelectedValue.ToString();
            int dimension = 1;
            if (colC > 1) dimension = 2;

            if (matrix != null)
            {
                //update existing entry
                int slab_id = matrix.getSlabId();
                string setpart = " SlabName = '" + slabName + "', FromDate = '" + fromDate.ToString("yyyy-MM-dd") + "', ToDate = '" + toDate.ToString("yyyy-MM-dd") + "',";
                setpart += " SlabType = '" + dimension.ToString() + "', ROperator = '" + rowOp + "', COperator = '" + colOp + "', Status = '" + status + "', IsStepped = '" + slabType;
                setpart += "', RFormula = '" + DDLFunctionR.SelectedValue.ToString() + "', CFormula = '" + DDLFunctionC.SelectedValue.ToString() + "'";
                string updateQ = "Update Slabs SET " + setpart + " WHERE SlabId = '" + slab_id + "'";// SET SlabName = '" + slabName + "'";

                DataBaseMethods.ExecuteNonQuery(updateQ);
                return slab_id;
            }

            //create and execute insert command in Slabs table
            string insertCommand = "INSERT INTO Slabs(SlabName,ProductName,FromDate,ToDate,SlabType,ROperator,COperator,Status,IsStepped,CreatedOn,CreatedBy,RFormula,CFormula)" +
                "VALUES('" + slabName + "','" + Session["ProductName"].ToString() + "','" + fromDate.ToString("yyyy-MM-dd") + "','" + toDate.ToString("yyyy-MM-dd") + "','" + dimension.ToString() + "','" + rowOp + "','" +
                colOp + "','" + status + "','" + slabType + "',getDate(),'" + Session["loginId"].ToString() + "','" + DDLFunctionR.SelectedValue + "','" + DDLFunctionC.SelectedValue + "' ) ";
            int slab_id2 = DataBaseMethods.ExecuteIdentityInsert(insertCommand, "SlabId");

            return slab_id2;
        }
        #endregion

        #region create table for matrix display
        private void createMatrixStructure()
        {
            //create non-header part
            for (int i = 0; i < matrix.getRowCount(); i++)
            {
                TableRow row = new TableRow();
                for (int j = 0; j < matrix.getColumnCount(); j++)
                {
                    TableCell column = new TableCell();
                    column.Controls.Add(getNonHeaderTextBox(i, j));
                    row.Cells.Add(column);
                } //column loop
                PanelTable.Rows.Add(row);
            }

            //add headers also
            addHeaders();

            return;
        }

        private void addHeaders()
        {
            //add column header for 2d only
            if (matrix.getColumnCount() > 1)
            {
                //add column headers
                TableHeaderRow hrow = new TableHeaderRow();
                for (int i = 0; i < matrix.getColumnCount(); i++)
                    hrow.Cells.Add(getHeaderCell(matrix.getCOper()));
                PanelTable.Rows.AddAt(0, hrow);

                //display HEADER at position 0,0
                TextBox tb = getNonHeaderTextBox(-1, -1);
                tb.Text = "Header";
                tb.Enabled = false;
                TableCell zzCell = new TableCell();
                zzCell.Controls.Add(tb);
                PanelTable.Rows[0].Cells.AddAt(0, zzCell);

                for (int i = 1; i <= matrix.getRowCount(); i++)
                    PanelTable.Rows[i].Cells.AddAt(0, getHeaderCell(matrix.getROper()));
            }
            else    //add row header 1d
            {
                for (int i = 0; i < matrix.getRowCount(); i++)
                    PanelTable.Rows[i].Cells.AddAt(0, getHeaderCell(matrix.getROper()));
            }
            return;
        }

        private TableCell getHeaderCell(string oper)
        {
            TableCell hCell = new TableCell();

            //tb for sign
            TextBox tb1 = new TextBox();
            tb1.Width = 20;
            tb1.Text = oper;
            tb1.Enabled = false;
            tb1.BackColor = System.Drawing.Color.Aqua;
            hCell.Controls.Add(tb1);

            //tb for value
            TextBox tb2 = new TextBox();
            tb2.Width = 60;
            tb2.BackColor = System.Drawing.Color.Aqua;
            hCell.Controls.Add(tb2);

            return hCell;
        }

        private TextBox getNonHeaderTextBox(int r, int c)
        {
            TextBox tb = new TextBox();
            tb.Width = 82;
            tb.ID = "TextBox_" + r.ToString() + c.ToString();
            return tb;
        }
        #endregion

        #region converts matrix v/s flat
        private void loadMatrix()
        {
            DataTable flatDt = matrix.getFlatMatrix();
            foreach (DataRow dr in flatDt.Rows)
            {
                int r = Convert.ToInt32(dr[1].ToString());
                int c = Convert.ToInt32(dr[2].ToString());
                string value = dr[3].ToString();

                TableCell tc = PanelTable.Rows[r].Cells[c];
                ControlCollection cc = tc.Controls;
                for (int i = 0; i < tc.Controls.Count; i++)
                {
                    if (tc.Controls[i] is TextBox)
                    {
                        TextBox tb = (TextBox)tc.Controls[i];
                        if (!tb.Enabled) continue;
                        if ((r == 0) || (c == 0))
                            tb.Text = value;
                        else
                            tb.Text = Convert.ToDouble(value).ToString();
                    }
                }
            }//done with row

            return;
        }

        private DataTable saveMatrix()
        {
            DataTable flatDt = matrix.getFlatMatrix();
            foreach (DataRow dr in flatDt.Rows)
            {
                int r = Convert.ToInt32(dr[1].ToString());
                int c = Convert.ToInt32(dr[2].ToString());

                TableCell tc = PanelTable.Rows[r].Cells[c];
                ControlCollection cc = tc.Controls;
                for (int i = 0; i < tc.Controls.Count; i++)
                {
                    if (tc.Controls[i] is TextBox)
                    {
                        TextBox tb = (TextBox)tc.Controls[i];
                        if (!tb.Enabled) continue;
                        try
                        {
                            dr[3] = Convert.ToDouble(tb.Text).ToString();
                        }
                        catch (Exception)
                        {
                            dr[3] = "0";
                            if ((r == 0) || (c == 0))
                                dr[3] = tb.Text;
                        }
                    }
                }
            } // done with row

            flatDt.AcceptChanges();
            return flatDt;
        }
        #endregion
    }
}